/*
 * common.cpp
 *
 *  Created on: Apr 30, 2011
 *      Author: tqlong
 */

#include <armadillo>
#include <cassert>
#include "common.h"

using namespace arma;

QTextStream Log::m_log(stdout);

/**  format = text, bin, raw
 *      bin: (long long)n  (long long d)
 *           n arma_binary vectors
 *      text: n d
 *           n arma_ascii vectors
 *      raw: (long long d)
 *           n x d doubles
 */
int common::loadVVec(const std::string&  fName, std::vector<vec>& vvec,
    const std::string& format)
{
	Log::m_log << "format=" << QString::fromStdString(format) << endl;
	std::ifstream is(fName.c_str());
	if (!is.good())
	{
		Log::m_log << "Cannot open " << QString::fromStdString(fName) << endl;
		return 0;
	}
	Log::m_log << "Reading " << QString::fromStdString(fName) << endl;
	char type[4] = "000";
	is.read(type, 3);

	if (format != type)
	{
		Log::m_log << "Incorrect format=" << QString::fromStdString(format)
		    << " file format=" << type << endl;
	}

	if (format == "txt")
	{
		long long n, d;
		is >> n >> d;

		Log::m_log << "n=" << n << " d=" << d << endl;
		vvec.clear();
		for (int i = 0; i < n && !is.eof(); i++)
		{
			vvec.push_back(vec(d));
			vec& v = vvec.back();
			v.load(is, arma::arma_ascii);
			assert(v.n_elem == d);
			//Log::m_log << "v[" << i << "]" << endl;
		}
	}
	else if (format == "bin")
	{
		long long n, d;
		binary_read(is, n);
		binary_read(is, d);

		Log::m_log << "n=" << n << " d=" << d << endl;
		vvec.clear();
		for (int i = 0; i < n && !is.eof(); i++)
		{
			vvec.push_back(vec(d));
			vec& v = vvec.back();
			v.load(is, arma::arma_binary);
			assert(v.n_elem == d);
			//Log::m_log << "v[" << i << "]" << endl;
		}
	}
	else if (format == "raw")
	{
		long long n_file, n, d, vec_size;
		binary_read(is, n_file);
		binary_read(is, d);
		vvec.clear();
		for (n = 0, vec_size = d * sizeof(double); ; n++)
		{
			vvec.push_back(vec(d));
			double* dptr = vvec.back().memptr();

			is.read((char*) dptr, vec_size);
			if (is.eof()) break;
		}
		vvec.resize(n);
		Log::m_log << "n_file = " << n_file << " n=" << n << " d=" << d << endl;
	}
	else
	{
		Log::m_log << "not recognized file format, use txt, bin, raw" << endl;
	}
	is.close();
	return vvec.size();
}
